In [78]:
import json
import plotly.graph_objects as go
import numpy as np
import pandas as pd

#
# read the mapbox access token to enable 'satellite' and 'satellite-streets' styles:
#
with open('./mapbox-access-token.txt') as f:
    token = f.read()



# Read quadrants dataset

import json

with open('./OGA_Quadrants_WGS84.geojson','r') as f:
    quads = json.load(f)

# Flatten the hierarchy

from flatten_geojson import flatten_geojson
df_quads = flatten_geojson(quads)

# Read quadrants dataset
with open('./OGA_Licences_WGS84.geojson','r') as f:
    licences = json.load(f)

# Activate to see the data: df_quads.info()
# Activate to see the data: df_quads.head()

# Read license blocks
with open('./OGA_Licences_WGS84.geojson','r') as f:
    licences = json.load(f)

# Flatten the geojson license blocks dataset
df_licences = flatten_geojson(licences)

# Activate to see the data: df_licences.info()
# Activate to see the data: df_licences.head()

# Read offshore fields determination
with open('./OGA_Offshore_FieldDets_WGS84.geojson','r') as f:
    dets = json.load(f)

# Flatten the geojson offshore blocks dataset
df_dets = flatten_geojson(dets)

# Activate to see the data: df_dets.info()
# Activate to see the data: df_dets.head()

# Read offshore fields
with open('./OGA_Offshore_Fields_WGS84.geojson','r') as f:
    fields = json.load(f)
    
# Flatten the geojson offshore blocks dataset
df_fields = flatten_geojson(fields)

# Activate to see the data: df_fields.info()
# Activate to see the data: df_fields.head()
# Activate to see the data: df_fields.FIELDTYPE.unique()
# Activate to see the data: df_fields.FIELDTYPE.value_counts()

# Create Basemap
# 1. create an empty figure:
#
fig = go.Figure()

#
# 2. add quadrants as filled polygons (for which a choropleth is just a fancy name):
#
# complete your solution by setting geojson and locations arguments
fig.add_choroplethmapbox(
    geojson=quads,
    locations=df_quads.OBJECTID,
    z=np.zeros_like(df_quads.QUAD_NO),
    name='Quadrants',
    colorscale=[[0, 'LightSkyBlue'], [1, 'LightSkyBlue']],
    visible=True,
    marker_opacity=0.2,
    marker_line_width=1,
    marker_line_color='White',
    showlegend=True,
    showscale=False,
    hovertext=df_quads.QUAD_NO,
    hovertemplate='Quad %{hovertext}<extra></extra>'
)

#
# 3. set background style, default zoom level, default center, and remove plot margins to make better use of the screen space:
#
# complete your solution by setting a mapbox_style
fig.update_layout(
    mapbox_style='satellite-streets',
    mapbox_accesstoken=token,
    mapbox_zoom=4,
    mapbox_center={"lat": 56.00, "lon": -2.00},
    margin={"r":0,"t":0,"l":0,"b":0}
)

#
# 4. style the legend:
#
# complete your solution by setting legend_title_text
fig.update_layout(
    showlegend=True,
    legend_title_text='UK Continental Shelf E&P Basemap<br><br>Created by David Psaila<br>',
    legend_title_font_color='White',
    legend_title_font_family='Helvetica',
    legend_font_color='White',
    legend_font_family='Helvetica',
    legend_x=0.005,
    legend_y=0.995,
    legend_bgcolor='Black'
)

#
# 5. add an attribution statement for the data:
#
fig.add_annotation(
    x=+0.05,
    y=+0.005,
    showarrow=False,
    text="Contains information provided by the Oil and Gas Authority.",
    font_color='White',
    font_size=10,
    font_family='Helvetica',
    xref="paper",
    yref="paper",
    xanchor='left',
    yanchor='bottom'
)

#
# 6. show basemap:
#
#fig.show()

#
# add licence blocks as filled polygons as a layer on top of the quadrants:
#
# complete your solution by setting geojson and locations arguments
fig.add_choroplethmapbox(
    geojson=licences,
    locations=df_licences.OBJECTID,
    z=np.zeros_like(df_licences.RNDNO),
    name='Licences',
    colorscale=[[0,'LightYellow'],[1,'LightYellow']],
    visible=True,
    marker_opacity=0.7,
    marker_line_width=0.5,
    marker_line_color='White',
    showlegend=True,
    showscale=False,
    hovertext=df_licences.BLOCKREF,
    hovertemplate='Licence %{hovertext}<extra></extra>'
)

#
# show basemap:
#
#fig.show()

#
# add field determinations as outline polygons as a layer on top of the licence blocks:
#
# complete your solution by setting geojson and locations arguments
fig.add_choroplethmapbox(
    geojson=dets,
    locations=df_dets.OBJECTID,
    z=np.zeros_like(df_dets.OBJECTID),
    name='Determinations',
    colorscale=[[0,'rgba(0,0,0,0)'],[1,'rgba(0,0,0,0)']],
    visible=True,
    marker_opacity=1,
    marker_line_width=1,
    marker_line_color='Magenta',
    legendgroup='Determinations',
    showlegend=False,
    showscale=False,
    hovertext=df_dets.FIELDNAME,
    hovertemplate='Determination %{hovertext}<extra></extra>'
)

#
# add an empty line so that determinations are indicated by a line in the map legend:
#
fig.add_scattermapbox(
    lon=[np.nan],
    lat=[np.nan],
    name='Determinations',
    marker_color='Magenta',
    legendgroup='Determinations',
    mode='lines',
    showlegend=True
)
    
#
# show basemap:
#
#fig.show()

#
# make a colour map for 'FIELDTYPE':
#
fieldtype_colour_map = {
    'GAS':  'Salmon',
    'COND': 'NavajoWhite',
    'OIL':  'YellowGreen',
}

#
# loop over each field type (GAS,COND,OIL):
#
for key,value in fieldtype_colour_map.items():
    #
    # get all the field areas of `FIELDTYPE == key`:
    #
    df_fields_type = df_fields.query('FIELDTYPE == @key')

    #
    # add fields areas of `FIELDTYPE == key` as filled polygons with the specified colour: 
    #
    fig.add_choroplethmapbox(
        geojson=fields,
        locations=df_fields_type.OBJECTID,
        z=np.zeros_like(df_fields_type.OBJECTID),
        name=key,
        colorscale=[[0,value],[1,value]],
        visible=True,
        marker_opacity=0.8,
        marker_line_width=0.5,
        marker_line_color='white',
        legendgroup='Fields',
        showlegend=True,
        showscale=False,
        hovertext=df_fields_type.FIELDNAME,
        hovertemplate='Field %{hovertext}<extra></extra>'
    )

#
# show basemap:
#
#fig.show()

#
# read the well header data from (.csv) file into a pandas data frame:
#
# complete your solution by reading the file into a data frame
df_wells = pd.read_csv('./OGA_Wells_WGS84.csv', low_memory=False)

#
# report info about the columns:
#

#
# overlay well surface locations:
#
fig.add_scattermapbox(
    lon=df_wells.X,
    lat=df_wells.Y,
    name='Well surface locations',
    marker_color='OrangeRed',
    marker_size=5,
    marker_opacity=1,
    text=df_wells.WELLREGNO,
    textposition='top right',
    textfont_color='white',
    textfont_size=11,
    mode='markers+text',
    hovertemplate='Well %{text}<br>(%{lon:.6f}&deg;E,%{lat:.6f}&deg;N)<extra></extra>'
)

#
# show figure:
#
#fig.show()

# complete your solution by reading the file into a data frame
df_esp = pd.read_csv('./esp-cdp-locations-wgs84.csv')

# df_esp.info()
# df_esp.head()

#
# add CDP locations using the same decimated dataset:
#
fig.add_scattermapbox(
    name='East Shetland Platform Survey',
    lon=df_esp.CDP_LON,
    lat=df_esp.CDP_LAT,
    customdata=df_esp,
    hovertemplate='<b>%{customdata[0]}</b><br>Line number %{customdata[1]}<br>Trace %{customdata[3]}<br>CDP %{customdata[2]}<br>(%{lon:.6f}&deg;E, %{lat:.6f}&deg;N)<extra></extra>',
    mode='lines+markers',
    line_color='chartreuse',
    line_width=1,
    marker_symbol='circle',
    marker_color='chartreuse',
    marker_size=3,
    connectgaps=False
)

#
# show figure:
#
fig.show()